#include "xx_tool.h"
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <PubSubClient.h>

const char *ssid = "";
const char *password = "";

// const char *ssid = "YK_DYNAMIC";
// const char *password = "yk123456";

const char *esp_ssid = "XXESP8266";      // 热点名称
const char *esp_password = "12345678XX"; // 热点密码

// 替换为您的MQTT代理地址和端口
const char *mqttServer = "8.137.99.64";
const int mqttPort = 1883;

// 替换为您的MQTT用户名和密码（如果需要）
const char *mqttUser = "zhaonx";
const char *mqttPassword = "Zhaonx123..";
// 设备类型
const String device_type = "LED";

// MQTT主题
const String topic_search = "P/S";
const String topic_heart = "P/H";
const String topic_answer = "P/A";
const String topic_work = "LED";

WiFiClient espClient;
PubSubClient client(espClient);
ESP8266WebServer server; // 声明成员变量
String macAddress = "";

// 函数声明
void handleRoot();
void handleConnect();
// 连接到WiFi
void setupWiFi()
{
    if (isNull(ssid) || isNull(password))
    {
        print_char("start softAP and HTTP server");
        WiFi.softAP(esp_ssid, esp_password); // 启动ap

        // 扫描周边Wi-Fi网络
        int n = WiFi.scanNetworks();
        String options = "";
        for (int i = 0; i < n; ++i)
        {
            options += "<option value=\"";
            options += WiFi.SSID(i);
            options += "\">";
            options += WiFi.SSID(i);
            options += " (";
            options += (WiFi.encryptionType(i) == AUTH_OPEN) ? "Open" : "Secured";
            options += ") - ";
            options += WiFi.RSSI(i);
            options += " dBm</option>";
        }

        // 创建主页路由
        server.on("/", HTTP_GET, [options]()
                  {
                String html = "<!DOCTYPE html><html><head><title>ESP32 Config</title></head><body>"
                  "<h2>Select WiFi Network</h2>"
                  "<form action=\"/set\" method=\"post\">"
                  "<label for=\"ssid\">SSID:</label>"
                  "<select name=\"ssid\" id=\"ssid\">";
                html += options;
                html += "</select><br><br>"
            "<label for=\"pass\">Password:</label>"
            "<input type=\"password\" name=\"pass\" id=\"pass\"><br><br>"
            "<input type=\"submit\" value=\"Submit\"></form></body></html>";
            server.send(200, "text/html", html); });

        // 处理表单提交
        server.on("/set", HTTP_POST, [](){
            if (server.hasArg("ssid") && server.hasArg("pass"))
            {
                ssid = server.arg("ssid").c_str();
                password = server.arg("pass").c_str();

                // 重新连接 WiFi
                setupWiFi();
                server.send(200, "text/plain", "Configuration updated successfully!");
            }
            else
            {
                server.send(400, "text/plain", "Bad Request: Missing SSID or Password.");
            } 
        });

        server.begin(); // 启动http服务
    }
    else
    {
        WiFi.begin(ssid, password);
        int attempts = 0;
        while (WiFi.status() != WL_CONNECTED && attempts < 30) // 等待连接或超时
        {
            delay(1000);
            print_char(".");
            attempts++;
        }
        if (WiFi.status() == WL_CONNECTED)
        {
            print_char("\nConnected to WiFi!");
            macAddress = WiFi.macAddress();
            server.send(200, "text/plain", device_type + "/" + macAddress);
            delay(1000);
            server.stop();               // 停止 HTTP 服务器
            WiFi.softAPdisconnect(true); // 断开 AP 热点
        }
        else
        {
            print_char("\nFailed to connect. Restarting hotspot...");
            WiFi.softAP(esp_ssid, esp_password); // 启动ap
            server.send(500, "text/plain", "Failed to connect. Hotspot restarted.");
        }
    }
}

// MQTT
// 连接到MQTT代理
void (*handleReceivedMessage)(String, String) = [](String topic, String message) {}; // 默认为空操作

void xx_mqtt_sendMessage(String topic, String message)
{
    client.publish(topic.c_str(), message.c_str());
}

// 发送心跳
void sendHeartBeat()
{
    String fullString = device_type + "/" + macAddress;
    xx_mqtt_sendMessage(topic_heart, fullString);
    print_char("heartBeat");
    print_char(fullString.c_str());
}

// 处理接收到的消息
void callback(char *topic, byte *payload, unsigned int length)
{
    // 协议
    String topic_type = "";
    for (int i = 0; i < strlen(topic); i++)
    {
        topic_type += (char)topic[i];
    }
    // 消息
    String message = "";
    for (int i = 0; i < length; i++)
    {
        message += (char)payload[i];
    }

    print_char(topic_type.c_str());
    print_char(message.c_str());

    if (topic_type.equals(topic_search))
    {
        // 发送心跳
        sendHeartBeat();
    }
    else
    {
        // 在这里调用外部传入的处理函数
        handleReceivedMessage(topic_type, message);
    }
}

void reconnect()
{
    while (!client.connected())
    {
        print_char("Attempting MQTT connection...");
        if (client.connect("ESP8266Client", mqttUser, mqttPassword))
        {
            print_char("MQTT connected");
            // 订阅公共消息
            client.subscribe(topic_search.c_str());
            // 订阅工作消息  topic_work +mac
            char fullString[40]; // 17 个字符 + 1 个结束符
            snprintf(fullString, sizeof(fullString), "%s/%s", topic_work.c_str(), macAddress.c_str());
            client.subscribe(fullString);

            // 发送心跳
            sendHeartBeat();
        }
        else
        {
            print_char("failed, rc=");
            print_int(client.state());
            print_char(" try again in 5 seconds");
            delay(5000);
        }
    }
}

// 提供给外部的接口，用于处理接收到的消息
void xx_mqtt_setOnMessageReceived(void (*func)(String, String))
{
    handleReceivedMessage = func;
}

void xx_mqtt_setup()
{
    setupWiFi(); // 配置网络
    client.setServer(mqttServer, mqttPort);
    client.setCallback(callback);
}

void xx_mqtt_loop()
{
    if (WiFi.status() == WL_CONNECTED)
    { // 已连接
        if (!client.connected())
        {
            reconnect();
        }
        client.loop();
    }
    else
    {                          // 配网
        server.handleClient(); // 处理客户端请求
    }
}